package server

import (
	"bytes"
	"encoding/xml"
	"io/ioutil"
	"log"
	"net/http"
	"open-platform/encryptor"
	"open-platform/repositories"
	"open-platform/xmlstruct"
	"os"
	"strconv"
)

func setTicket(w http.ResponseWriter, r *http.Request) {

	urlQuery := r.URL.Query()

	timestamp := urlQuery.Get("timestamp")
	nonce := urlQuery.Get("nonce")
	msgSignature := urlQuery.Get("msg_signature")

	postData, err := ioutil.ReadAll(r.Body)

	if nil != err {
		response(w, "系统错误", "500")
		return
	}

	if "" == timestamp || "" == nonce || "" == msgSignature {
		response(w, "参数错误", "400")
		return
	}

	timestampInt, err := strconv.Atoi(timestamp)

	if nil != err {
		response(w, "系统错误", "500")
	}

	var authorizeEncrypt xmlstruct.AuthorizeEncrypt
	err = xml.Unmarshal([]byte(postData), &authorizeEncrypt)

	if nil != err {
		response(w, "系统错误", "500")
	}

	var appId string = authorizeEncrypt.AppId.Text

	openPlatform, err := repositories.OpenPlatformReposition.GetByAppId(appId)

	if nil != err {
		response(w, "系统错误", "500")
		return
	}

	decryptMsg := encryptor.DecryptMsg{
		msgSignature,
		timestampInt,
		nonce,
		authorizeEncrypt.Encrypt.Text,
	}

	messageCryptor, _ := encryptor.New(
		openPlatform["token"].(string),
		openPlatform["key"].(string),
		appId,
	)

	msg, err := messageCryptor.Decrypt(&decryptMsg)

	if nil != err {
		response(w, err.Error(), "500")
	} else {

		logFile, _ := os.Create("tqtset.txt")
		defer logFile.Close()
		debugLog := log.New(logFile, "ticket", log.Ldate)
		debugLog.Println(string(msg))

		infoTypeStr := getInfoType(msg)
		debugLog.Println(string(infoTypeStr))

		autoHandler(string(infoTypeStr), msg)

	}

}

var infoType = []byte{60, 73, 110, 102, 111, 84, 121, 112, 101, 62}

func handlerTicket(msg []byte) {

	var componentVerifyTicket xmlstruct.ComponentVerifyTicket

	err := xml.Unmarshal(msg, &componentVerifyTicket)

	if nil != err {
		return
	}

	_, err = repositories.OpenPlatformReposition.SaveTicket(
		componentVerifyTicket.AppId.Text,
		componentVerifyTicket.ComponentVerifyTicket.Text,
	)

	if nil != err {
		return
	}

}

func autoHandler(infoTypeStr string, msg []byte) {

	switch infoTypeStr {
	case "component_verify_ticket":
		handlerTicket(msg)
	}

}

func getInfoType(msg []byte) []byte {

	index := bytes.Index(msg, infoType)

	if 0 > index {
		return []byte{}
	}

	startIndex := index + len(infoType) + 9
	var endIndex int = startIndex

	for i := startIndex; i < len(msg); i++ {

		if 93 == msg[i] {
			break
		}

		endIndex++

	}

	return msg[startIndex:endIndex]

}
